package com.springbootblog.service.serviceImpl.fontend;

import com.fasterxml.jackson.databind.JsonNode;
import com.springbootblog.controller.fontend.IndexController;
import com.springbootblog.dao.UserDao;
import com.springbootblog.pojo.User;
import com.springbootblog.service.fontend.LoginService;
import com.springbootblog.utils.*;
import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Service
public class LoginServiceImpl implements LoginService
{
    /**
     * 定义一个静态常量日志对象
     */
    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);

    /**
     * 自动装载（dao接口注入）
     */
    @Autowired
    private UserDao userDao;

    /**
     * 注入redis类
     */
    @Autowired
    private RedisUtil redisUtil;

    @Value("${spring.AES.key}")
    public String key;
    @Value("${spring.AES.iv}")
    public String iv;

    /**
     * 登录/注册/忘记密码
     * @param params
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> accountLogin(String params, HttpServletRequest request) throws Exception
    {
        // 前端AES加密，后端AES解密
        String str = AES.decryptAES(params,this.key,this.iv);
        //        System.out.println(str);
        //        System.out.println(this.key);
        //        System.out.println(this.iv);
        // 获取key对应的值
        // 操作标识 登录/注册/忘记密码
        String sign = Function.stringToJson(str,"sign");
        // 邮箱
        String email = Function.stringToJson(str,"email");
        // 密码
        String password = Function.stringToJson(str,"password");
        // 邮箱验证码
        String emailCode = Function.stringToJson(str,"emailCode");
        // 获取session对象
        // HttpSession session = request.getSession();
        // 登录
        if(sign.equals("login"))
        {
            // 查用户信息
            User userinfo = userDao.getUserByEmail(email);
            String pass = userinfo.getJava_password();
            if(pass == null || pass.isEmpty())
            {
                Map<String,Object> result = new HashMap<>(2);
                result.put("code", -2);
                result.put("msg", "未设置密码！");
                return result;
            }
            if(!pass.equals(MD5.md5(password, "")))
            {
                Map<String,Object> result = new HashMap<>(2);
                result.put("code", -2);
                result.put("msg", "账号或密码错误！");
                return result;
            }
        }
        else if(sign.equals("register"))
        {// 注册
            if(emailCode == "" || emailCode == null || emailCode.isEmpty())
            {
                Map<String,Object> result = new HashMap<>(2);
                result.put("code", -3);
                result.put("msg", "验证码为空！");
                return result;
            }
            // Object emailCodeSession = session.getAttribute("emailCode");
            // 从redis中获取邮箱验证码
            String emailCodeSession = String.valueOf(redisUtil.get("emailCode_"+email));
            System.out.println(emailCodeSession);
            System.out.println(emailCode);
            if(!emailCode.equals(emailCodeSession))
            {
                Map<String,Object> result = new HashMap<>(2);
                result.put("code", -4);
                result.put("msg", "验证码错误！");
                return result;
            }
            // 查用户信息
            User userinfo = userDao.getUserByEmail(email);
            if(userinfo != null)
            {
                Map<String,Object> result = new HashMap<>(2);
                result.put("code", -5);
                result.put("msg", "这个账号已经注册！");
                return result;
            }
            String PassStr = MD5.md5(password, "");
            User user = new User();
            user.setPassword(PassStr);
            user.setEmail(email);
            userDao.addUser(user);
            Integer id = user.getId();
//            System.out.println("Userid:"+id);
        }
        else if(sign.equals("password"))
        {// 忘记密码
            if(emailCode == null || emailCode.isEmpty())
            {
                Map<String,Object> result = new HashMap<>(2);
                result.put("code", -3);
                result.put("msg", "验证码为空！");
                return result;
            }
            // Object emailCodeSession = session.getAttribute("emailCode");
            // 从redis中获取邮箱验证码
            Object emailCodeSession = redisUtil.get("emailCode_"+email);
            if(emailCode != emailCodeSession)
            {
                Map<String,Object> result = new HashMap<>(2);
                result.put("code", -4);
                result.put("msg", "验证码错误！");
                return result;
            }
            String PassStr = MD5.md5(password, "");
            userDao.updateUserPassword(PassStr,email);
        }
        // 创建一个Random对象
        Random random = new Random();
        // 生成登录唯一标识
        Integer dates = random.nextInt(999999 - 111111 + 1) + 111111;
        Integer time = (int) (System.currentTimeMillis() / 1000);
        String user_login_key = time + "_" + dates;
        // 更新用户唯一标识
        userDao.updateUserKey(user_login_key, email);
        // 查用户信息
        User userinfo = userDao.getUserByEmail(email);
        String figureurl = "http://thirdqq.qlogo.cn/g?b=oidb&k=chKV5fa4V6wqcOuTiatmibHQ&s=100&t=1555469889";
        if(userinfo.getFigureurl_qq() != null)
        {
            figureurl = userinfo.getFigureurl_qq();
        }
        else if(userinfo.getFigureurl_wx() != null)
        {
            figureurl = userinfo.getFigureurl_wx();
        }
        // 存session
        /*session.setAttribute("id",userinfo.getId());
        session.setAttribute("userid",userinfo.getId());
        session.setAttribute("figureurl",figureurl);
        session.setAttribute("nickname",userinfo.getNickname());
        session.setAttribute("email",userinfo.getEmail());
        session.setAttribute("user_login_key",userinfo.getUser_login_key());//*/

        Map<String,Object> sessionMap = new HashMap<>();
        sessionMap.put("id", userinfo.getId());
        sessionMap.put("userid", userinfo.getId());
        sessionMap.put("figureurl", figureurl);
        sessionMap.put("nickname", userinfo.getNickname());
        sessionMap.put("email", userinfo.getEmail());
        sessionMap.put("user_login_key", userinfo.getUser_login_key());
        String token = JwtUtils.createJWT(sessionMap);

        Map<String,Object> result = new HashMap<>(6);
        result.put("token", token);
        result.put("userid", userinfo.getId());
        result.put("figureurl", figureurl);
        result.put("nickname", userinfo.getNickname());
        result.put("email", userinfo.getEmail());
        result.put("code", 1);
        result.put("msg", "操作成功");
        return result;
    }

    /**
     * 注入邮箱类
     */
    @Autowired
    private Email emailObj;

    /**
     * 发邮箱
     * @param params
     * @param request
     * @return
     */
    @Override
    public Map<String, Object> sendEmailCode(String params, HttpServletRequest request) throws Exception {
        // 前端AES加密，后端AES解密
        JsonNode str = Function.strToJson(params);
        String json = str.get("params").toString();
        String strs = AES.decryptAES(json,this.key,this.iv);
        // System.out.println(strs);
        // 邮箱
        String email = Function.stringToJson(strs,"email");
        System.out.println(email);
        // System.out.println(str);
        if(email.isEmpty())
        {
            Map<String,Object> result = new HashMap<>(2);
            result.put("code", -1);
            result.put("msg", "参数错误！");
            return result;
        }
        // 生成6位随机数
        Random random = new Random();
        int emailCode = (random.nextInt(900000) + 100000);
        // 获取session对象
        // HttpSession session = request.getSession();
        // session.setAttribute("emailcode",emailCode);
        String key = "emailCode_"+email;
        // 将验证码写入redis，过期时间10分钟
        redisUtil.set(key,emailCode,600);
        System.out.println(key);
        System.out.println(emailCode);

        String content = "您在时间里的博客中的邮箱验证码为："+ emailCode+",10分钟内有效！";
        emailObj.sendSimpleMail(email,"时间里的博客",content);

        Map<String,Object> result = new HashMap<>(2);
        result.put("code", 1);
        result.put("msg", "操作成功！");
        return result;
    }

    /**
     * 修改昵称
     * @param params
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> updateNickname(String params, HttpServletRequest request) throws Exception
    {
        JsonNode str = Function.strToJson(params);
        JsonNode json = str.get("params");
        // 用户昵称
        String nickname = String.valueOf(json.get("nickname"));
        if(nickname == null || nickname.isEmpty())
        {
            Map<String,Object> result = new HashMap<>(2);
            result.put("code", -1);
            result.put("msg", "参数错误！");
            return result;
        }
        /*HttpSession session = request.getSession();
        String id = session.getAttribute("id").toString();//*/
        // 获取token
        String token = request.getHeader(JwtUtils.token_name);
        // 解析token
        Claims paramList = JwtUtils.parseJWT(token);
        String id;
        if(paramList == null || paramList.equals(null))
        {
            id = null;
        }
        else
        {
            id = paramList.get("id").toString();
        }
        //String id = paramList.get("id").toString();
        if(id == null || id.isEmpty())
        {
            Map<String,Object> result = new HashMap<>(2);
            result.put("code", -2);
            result.put("msg", "您没有登录！");
            return result;
        }
        // 修改数据库用户头像信息
        Integer res = userDao.updateUserNicknameById(id,nickname);

        nickname = Function.trimSelf(nickname,'"');
        // 重新生成jwt
        Map<String,Object> sessionMap = new HashMap<>();
        sessionMap.put("nickname", nickname);
        sessionMap.put("id", paramList.get("id"));
        sessionMap.put("userid", paramList.get("userid"));
        sessionMap.put("figureurl", paramList.get("figureurl"));
        sessionMap.put("email", paramList.get("email"));
        sessionMap.put("user_login_key", paramList.get("user_login_key"));
        String tokenAgiain = JwtUtils.createJWTagain(sessionMap,JwtUtils.getIssuedAtDateFromToken(token),JwtUtils.getExpirationDateFromToken(token));
        // 更新session
        // session.setAttribute("nickname", nickname);
        Map<String,Object> result = new HashMap<>(2);
        result.put("code", 1);
        result.put("msg", "操作成功！");
        result.put("token", tokenAgiain);
        return result;
    }

    /**
     * 单点登录方法
     * @param request
     * @return
     */
    public Map<String,Object> checkSingleLogin(HttpServletRequest request)
    {
        Map<String,Object> result = new HashMap<>();
        // 获取token
        String token = request.getHeader(JwtUtils.token_name);
        System.out.println("token:"+token);
        if( token == null || token == "null" || token.equals("") || token.equals("undefined"))
        {
            result.put("code", 1);
            result.put("msg", "操作成功！");
            return result;
        }
        // 解析token
        Claims paramList = JwtUtils.parseJWT(token);
        Object id;
        if(paramList == null || paramList.equals(null))
        {
            id = null;
        }
        else
        {
            id = paramList.get("id");
        }
        //System.out.println("解析后的token:"+paramList);
        // Object id = paramList.get("id");
        /*// 获取session对象
        HttpSession session = request.getSession();
        Object id = session.getAttribute("id");//*/
        if(id == null || id.equals(""))
        {
            //System.out.println("userid:"+id);
        }
        else if(id.toString().equals("1"))
        {// 我得账号，不需要单点登录

        }
        else
        {// 单点登录
            System.out.println("userid:"+id.toString());
            User userInfo = userDao.getUserInfoById(id.toString());
            System.out.println("userInfo:"+userInfo);

            String user_login_key = userInfo.getUser_login_key();
            //Object user_login_key_session = session.getAttribute("user_login_key");
            Object user_login_key_session = paramList.get("user_login_key");
            if(!user_login_key.equals(user_login_key_session.toString()))
            {
                // 清空session
                //session.invalidate();
                result.put("code", -150);
                result.put("msg", "您的账号在另一地点登录！");
                return result;
            }
        }
        result.put("code", 1);
        result.put("msg", "操作成功！");
        return result;
    }


}
